package com.david.warehouse.service.impl;

import com.david.common.utils.BatchNoUtils;
import com.david.common.utils.PageResult;
import com.david.system.mapper.UserMapper;
import com.david.system.pojo.Entity.UserEntity;
import com.david.system.pojo.Entity.WhType;
import com.david.warehouse.mapper.InventoryMapper;
import com.david.warehouse.pojo.entity.InboundDetail;
import com.david.warehouse.pojo.entity.InboundOrder;
import com.david.warehouse.pojo.entity.InboundVO;
import com.david.warehouse.pojo.entity.Inventory;
import com.david.warehouse.pojo.vo.*;
import com.david.warehouse.service.InventoryService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class InventoryServiceImpl implements InventoryService {
    @Autowired
    private InventoryMapper inventoryMapper;
    @Autowired
    private UserMapper userMapper;

    @Override
    public PageResult getInventoryList(InventorySearchVO searchVO, Boolean isAll) {
        PageHelper.startPage(searchVO.getPage(), searchVO.getPageSize());

        List<InventoryVO> inventoryVOList = inventoryMapper.selectInventoryList(searchVO, isAll);
        PageResult pageResult = new PageResult(inventoryVOList.size(), inventoryVOList);
        return pageResult;
    }

    @Override
    public InventoryDetailVO getInventoryDetailById(Integer id, Integer page, Integer pageSize) {
//        PageHelper.startPage(page, pageSize);
        InventoryVO inventoryVO = inventoryMapper.selectInventoryById(id);
//        List<InboundVO> inboundList = inventoryMapper.selectInboundListByProductIdWhId(inventoryVO.getProductId(), inventoryVO.getWhId());
//        PageResult inboundResult = new PageResult(inboundList.size(), inboundList);
        PageResult inboundResult = getInboundList(inventoryVO.getProductId(), inventoryVO.getWhId(), page, pageSize);
//        List<OutboundVO> outboundList = inventoryMapper.selectOutboundListByProductIdWhId(inventoryVO.getProductId(), inventoryVO.getWhId());
//        PageResult outboundResult = new PageResult(outboundList.size(), outboundList);
        PageResult outboundResult = getOutboundList(inventoryVO.getProductId(), inventoryVO.getWhId(), page, pageSize);
        InventoryDetailVO inventoryDetailVO = new InventoryDetailVO();
        inventoryDetailVO.setInventoryVO(inventoryVO);
        inventoryDetailVO.setInboundList(inboundResult);
        inventoryDetailVO.setOutboundList(outboundResult);
        return inventoryDetailVO;
    }

    @Override
    public PageResult getInboundList(Integer productId, Integer whId, Integer page, Integer pageSize) {
        PageHelper.startPage(page, pageSize);
        List<InboundVO> inboundVOList = inventoryMapper.selectInboundListByProductIdWhId(productId, whId);
        return new PageResult(inboundVOList.size(), inboundVOList);
    }

    @Override
    public PageResult getOutboundList(Integer productId, Integer whId, Integer page, Integer pageSize) {
        PageHelper.startPage(page, pageSize);
        List<OutboundVO> outboundVOList = inventoryMapper.selectOutboundListByProductIdWhId(productId, whId);
        return new PageResult(outboundVOList.size(), outboundVOList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addInbound(Integer typeId, InboundOrderAndDetails inboundOrderAndDetails) {
        // 查询type的code
        WhType whType = inventoryMapper.selectWhTypeById(typeId);
        // 生成batchNo
        String batchNo = BatchNoUtils.createBatchNo(whType.getCode());
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        UserEntity userEntity = userMapper.selectUserByUsername(username);
        inboundOrderAndDetails.getOrder().setCreateUserId(userEntity.getId());
        inboundOrderAndDetails.getOrder().setCreateTime(LocalDateTime.now());
        inboundOrderAndDetails.getOrder().setBatchNo(batchNo);
        inventoryMapper.insertInboundOrder(inboundOrderAndDetails.getOrder());
//        AtomicReference<Float> quantityTotal = new AtomicReference<>(0F);
        for (InboundDetail item : inboundOrderAndDetails.getDetails()) {
            item.setBatchNo(batchNo);
            item.setOperatorId(userEntity.getId());
            item.setCreateTime(LocalDateTime.now());
            // 修改inventory中的数据
            // TODO 未修改frozen的数据，需要相应的事件来触发，目前还没设计该类型事件
            Inventory inventory = new Inventory(null, item.getProductId(), inboundOrderAndDetails.getOrder().getWhId(), 0F, 0F, 0F);
            inventory.setProductId(item.getProductId());
            Inventory inventorySelected = Optional.ofNullable(inventoryMapper.selectInventory(inventory)).orElseGet(() -> (inventoryMapper.insertInventory(inventory)));
            Float quantityTotal = item.getQuantity() + inventorySelected.getTotal();
            Float dispensable = item.getQuantity()+ inventorySelected.getDispensable();
            inventorySelected.setTotal(quantityTotal);
            inventorySelected.setDispensable(dispensable);
            inventoryMapper.updateInventory(inventorySelected);
        }
        inventoryMapper.insertInboundDetailList(inboundOrderAndDetails.getDetails());

    }

    @Override
    public PageResult getInboundOrderList(InboundOrderVO inboundOrderVO) {
        PageHelper.startPage(inboundOrderVO.getPage(), inboundOrderVO.getPageSize());
        InboundOrder inboundOrder = new InboundOrder();
        BeanUtils.copyProperties(inboundOrderVO, inboundOrder);
        List<InboundOrder> inboundOrderList = inventoryMapper.selectInboundOrderByOrderAndCreatetime(inboundOrder, inboundOrderVO.getCreateTimeRange());
        PageResult pageResult = new PageResult(inboundOrderList.size(), inboundOrderList);
        return pageResult;
    }

    @Override
    public InboundOrderAndDetails getInboundAndDetail(String batchNo) {
        InboundOrder inboundOrder = new InboundOrder();
        inboundOrder.setBatchNo(batchNo);
        InboundOrder order = inventoryMapper.selectInboundOrder(inboundOrder);

        // details
        List<InboundDetail> inboundDetailList = inventoryMapper.selectInboundDetailByBatchNo(batchNo);

        InboundOrderAndDetails inboundOrderAndDetails = new InboundOrderAndDetails();
        inboundOrderAndDetails.setOrder(order);
        inboundOrderAndDetails.setDetails(inboundDetailList);
        return inboundOrderAndDetails;
    }
}
